iT邦幫忙

0

使用druidfi/stonehenge,實現 https + Domain Name 在Windows本機開發網路應用

  • 分享至 

  • xImage
  •  

撰寫者 : Cymon Dez
撰寫時間 : 2025-09-11

前言

筆者曾於2020年時撰寫過使用 SSL 與 Domain Name 在Windows本機開發後端應用一文。
隨著時間推移,如今(2025)已經有良好的開源套件druidfi/stonehenge可以輕鬆搭建此功能的開發環境,故決定寫一篇在Windows10/11 wsl2環境下,使用stonehenge搭建能夠使用SSL+Domain的本地開發環境。

目標

  1. 本機上的專案(前端、後端均可)可以使用SSL + Domain Name進行測試時
  2. 80,443 port 的複用,減少port衝突
  3. 減少修改 hosts檔案的麻煩
  4. 使用 VS2022整合docker-compose debug環境

適用場景

  1. 專案容器化開發
  2. 產品使用容器部屬

建置環境

以下是本篇文章撰寫時,所使用到的系統以及工具版版本

  • Win10 22H2
  • powershell 7.5.2
  • wsl2 2.5.10.0 with distribution Ubuntu-20.04
  • Docker Desktop 4.45.0
    • docker 28.3.3
    • docker compose v2.39.2-desktop.1
  • Visual Studio 2022 17.14.11
  • vscode 1.103.2
  • druidfi/stonehenge 5.1.0
    • traefik v3.5.0
    • Mailpit v1.27.7

stonehenge

簡介

stonehenge是一套藉由traefik + mkcert 實現本地https domain name開發環境的一套開源專案。
套件(5.x)由以下幾項整合

  • traefik:具備服務發現器與自動憑證申請的新一代服務發現器,與docker的相容性良好
  • mkcert:產生本機測試用途之可信任的SSL檔
  • Mailpit:email快取,用於測試專案的郵件發送機制

安裝前檢查

  1. 請先確認您的Windows10/11環境,已經安裝好wsl2docker
  2. 確認套件stonehenge預設會使用到的port未被其他服務占用,以下列出所需要的port以及功能:
    1. 80 port: http
    2. 443 port: https
    3. 1025 port: Mailpit

詳細安裝 (與快速安裝則一)

  1. 開啟powershell,在wsl2下安裝build-essential

    wsl sh -c "sudo apt update && sudo apt upgrade && sudo apt install build-essential"
    
  2. git clone stonehenge專案

    wsl git clone -b 5.x https://github.com/druidfi/stonehenge.git ~/stonehenge
    
  3. 如果需要調整安裝參數,請進到stonehenge/.env裡進行設定

    這邊使用vscode修改,您也可以將code改為nano或vim

    wsl code ~/stonehenge/.env
    

    可修改的參數如下:

    • DOCKER_DOMAIN:反向代理的root domain,預設值是docker.so,其原理是將*.docker.so指向127.0.0.1;如果想修改成自己單位使用的domain,請記得將設定的domain指向127.0.0.1
      | type | domain | ip address |
      | :--: | :--------------------------: | :--------: |
      | A | <your_organization_domain> | 127.0.0.1 |
      | A | *.<your_organization_domain> | 127.0.0.1 |
    • HTTP_PORT:http使用的port,預設值是80
    • HTTPS_PORT:https使用的prot,預設值是443
    • SMTP_PORT:smtp(email)使用的prot,預設值是1025
    # Root domain for all local services
    DOCKER_DOMAIN=docker.so
    
    # Prefix for containers
    PREFIX=stonehenge
    
    # Stonehenge major version
    STONEHENGE_VERSION=5
    
    # Image versions
    STONEHENGE_TAG=5.1
    
    # http port ,預設是 80,原始檔案沒有,須自己加上
    # HTTP_PORT=80
    
    # https port ,預設是 443,原始檔案沒有,須自己加上
    # HTTPS_PORT=443
    
    # smtp port ,預設是 1025,原始檔案沒有,須自己加上
    # HTTP_PORT=1025
    
  4. 安裝

    wsl make -s -C ~/stonehenge up
    
  5. 設定開發用憑證

     $WSL_NAME = $(wsl sh -c 'echo $WSL_DISTRO_NAME')
     $WSL_USER = $(wsl whoami)
     Import-Certificate -Filepath \\wsl$\$WSL_NAME\home\$WSL_USER\stonehenge\certs\rootCA.pem -CertStoreLocation cert:\CurrentUser\Root
    

快速安裝 (與詳細安裝則一)

如果打算都使用預設值,可以考慮使用作者撰寫的ps1直接安裝

iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/druidfi/stonehenge/5.x/install.ps1'))

檢測

在瀏覽器上,輸入下列網址,如果能順裡開起,代表安裝與設定皆正常:

!!!
提示:如果安裝時有修改DOCKER_DOMAIN,請使用您定的domain加上服務前綴測試
如:
traefik.<your_organization_domain>
mailpit.<your_organization_domain>

試著佈署一個服務 - 使用 traefik/whoami

traefik/whoami是一個輕量容器的Echo服務,功能如下:

  • 請求方法(GET、POST 等)
  • 請求的 Host 與 URL
  • HTTP Header
  • 來源 IP
  • TLS/HTTPS 相關資訊(如果有)

很適合用來測試traefik網路環境

  1. 在你的專案資料夾下,建一個新資料夾whoami

  2. whoami資料夾下,產生compose.yml檔並加入以下內容

    networks:
      # stonehenge 的traefik 所使用的docker network,於安裝時建立
      stonehenge-network:
        external: true
    services:
      app:
        image: traefik/whoami:latest
        labels:
          # 要使用字串的方式才能套用到環境變數
          # container啟用traefik反向代理功能
          - "traefik.enable=true"
    
          # stonehenge 的traefik 所使用的docker network,於安裝時建立
          - "traefik.docker.network=stonehenge-network"
    
          # ${COMPOSE_PROJECT_NAME} 會預設套用compose.yml所在的資料夾名稱,這樣可以盡量避免traefik route 名稱重複造成的衝突問題
          - "traefik.http.routers.${COMPOSE_PROJECT_NAME}.entrypoints=https"
          - "traefik.http.routers.${COMPOSE_PROJECT_NAME}.rule=Host(`whoami.docker.so`)"
          - "traefik.http.routers.${COMPOSE_PROJECT_NAME}.tls=true"
          - "traefik.http.services.${COMPOSE_PROJECT_NAME}.loadbalancer.server.port=80"
        networks:
          - default
          # 需要反向代理的服務才加入 stonehenge-network
          - stonehenge-network
    
  3. 啟動docker compose

    docker compose up -d
    
  4. 測試
    使用wsl的curl,輸入whoami.docker.so,檢測是否能連線並自動重新導向到https

    wsl curl -vL --ssl-revoke-best-effort whoami.docker.so
    # -v: 顯示詳細訊息
    # -L: 代表 follow redirect
    

    如果成功會看到以下訊息:

    * Host whoami.docker.so:80 was resolved.
    * IPv6: (none)
    * IPv4: 127.0.0.1
    *   Trying 127.0.0.1:80...
    * Connected to whoami.docker.so (127.0.0.1) port 80
    > GET / HTTP/1.1
    > Host: whoami.docker.so
    > User-Agent: curl/8.9.1
    > Accept: */*
    >
    < HTTP/1.1 301 Moved Permanently
    < Location: https://whoami.docker.so/
    < Date: Thu, 11 Sep 2025 16:35:00 GMT
    < Content-Length: 17
    * Ignoring the response-body
    <
    * Connection #0 to host whoami.docker.so left intact
    * Clear auth, redirects to port from 80 to 443
    * Issue another request to this URL: 'https://whoami.docker.so/'
    * Host whoami.docker.so:443 was resolved.
    * IPv6: (none)
    * IPv4: 127.0.0.1
    *   Trying 127.0.0.1:443...
    * Connected to whoami.docker.so (127.0.0.1) port 443
    * schannel: disabled automatic use of client certificate
    * ALPN: curl offers http/1.1
    * ALPN: server accepted http/1.1
    * using HTTP/1.x
    > GET / HTTP/1.1
    > Host: whoami.docker.so
    > User-Agent: curl/8.9.1
    > Accept: */*
    >
    < HTTP/1.1 200 OK
    < Content-Length: 377
    < Content-Type: text/plain; charset=utf-8
    < Date: Thu, 11 Sep 2025 16:35:00 GMT
    <
    Hostname: 36529239ef8f
    IP: 127.0.0.1
    IP: ::1
    IP: 172.19.0.3
    IP: 172.21.0.2
    RemoteAddr: 172.19.0.2:59848
    GET / HTTP/1.1
    Host: whoami.docker.so
    User-Agent: curl/8.9.1
    Accept: */*
    Accept-Encoding: gzip
    X-Forwarded-For: 172.19.0.1
    X-Forwarded-Host: whoami.docker.so
    X-Forwarded-Port: 443
    X-Forwarded-Proto: https
    X-Forwarded-Server: 68578e0bf36c
    X-Real-Ip: 172.19.0.1
    
    * Connection #1 to host whoami.docker.so left intact
    

    在traefik dashboard中,應該能看見http route有新增了 whoami.docker.so這項
    traefik-whoami

範例參考

stonehenge專案有提供很多佈署相關的範例,可以到stonehenge專案的examples查詢

如何用於開發專案

VS2022 使用 docker compose 支援

詳細內容請參考微軟官方教學

  1. 建立一個asp.net core 8 MVC專案
    create-aspnetcore-mvc-porj
    create-aspnetcore-mvc-porj-settings

  2. 加入docker compose 支援
    專案上按右鍵,選擇 [ 加入 > 容器協調器支援]。 [ Docker 支援選項 ]
    container-supports

    對話框出現後,選擇 [ Docker Compose]。
    docker-compose-supports

  3. 設定docker-compose.override.yml,加入stonehenge的網路設定
    docker-compose.override.yaml

    services:
      webapplication_stonehege_demo:
        environment:
          - ASPNETCORE_ENVIRONMENT=Development
          - ASPNETCORE_HTTP_PORTS=8080
        ports:
          - "8080"
        networks:
          - default
          - traefik-proxy
        labels:
          # 要使用字串的方式才能套用到環境變數
          # container啟用traefik反向代理功能
          - "traefik.enable=true"
    
          # stonehenge 的traefik 所使用的docker network,於安裝時建立
          - "traefik.docker.network=stonehenge-network"
    
          # ${COMPOSE_PROJECT_NAME} 會預設套用compose.yml所在的資料夾名稱,這樣可以盡量避免traefik route 名稱重複造成的衝突問題
          - "traefik.http.routers.${COMPOSE_PROJECT_NAME}.entrypoints=https"
          - "traefik.http.routers.${COMPOSE_PROJECT_NAME}.rule=Host(`webapp.docker.so`)"
          - "traefik.http.routers.${COMPOSE_PROJECT_NAME}.tls=true"
          - "traefik.http.services.${COMPOSE_PROJECT_NAME}.loadbalancer.server.port=8080"
    
    networks:
      traefik-proxy:
          name: stonehenge-network
          external: true
    

    請確認檔案是以UTF-8編碼儲存,不然啟動時會遇到 yaml: invalid leading UTF-8 octet這個錯誤
    yaml_invalid_leading_UTF-8_octet

  4. 修改docker-compose.dcproj

    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="15.0" Sdk="Microsoft.Docker.Sdk">
      <PropertyGroup Label="Globals">
        <ProjectVersion>2.1</ProjectVersion>
        <DockerTargetOS>Linux</DockerTargetOS>
        <DockerPublishLocally>False</DockerPublishLocally>
        <ProjectGuid>81dded9d-158b-e303-5f62-77a2896d2a5a</ProjectGuid>
        <DockerLaunchAction>LaunchBrowser</DockerLaunchAction>
        <!--將DockerServiceUrl修改改成 與override中相同的網址-->
        <DockerServiceUrl>https://webapp.docker.so</DockerServiceUrl>
        <DockerServiceName>webapplication_stonehege_demo</DockerServiceName>
      </PropertyGroup>
      <ItemGroup>
        <None Include="docker-compose.override.yml">
          <DependentUpon>docker-compose.yml</DependentUpon>
        </None>
        <None Include="docker-compose.yml" />
        <None Include=".dockerignore" />
      </ItemGroup>
    </Project>
    
  5. F5啟動專案測試
    如果設定正確 vs2022會啟動瀏覽器
    vs2022-debug-browser

    traefik dashboardhttp route會看到此專案的路由
    vs2022-debug-traefik

結語

透過 stonehenge,Windows 本機開發環境能夠輕鬆實現 SSL + Domain Name 的需求,並且大幅簡化設定流程。無論是前端或後端專案,都能享受一致且安全的本地測試體驗。stonehenge 讓容器化開發更貼近正式環境,減少 port 衝突與 hosts 檔案修改的困擾,也方便團隊協作與 CI/CD 部署。


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言